<template>
  <div class="page-randomCubes">
    <div class="canvas"></div>
  </div>
</template>
<script setup>
import {onActivated, onDeactivated, onMounted, onUnmounted, reactive} from "vue";
import * as Three from 'three';
import {OrbitControls} from "three/addons/controls/OrbitControls";
import {GUI} from "dat.gui";
import util from '../util';

let state = reactive({
  gui: null,
  taskFlag: true,
  axesFlag: true,
  addNum: 5
});
let scene = new Three.Scene();
let axes = new Three.AxesHelper(5);
let renderer = new Three.WebGLRenderer({antialias: true, alpha: true});
function getRandomColor() {
  return `rgb(${util.getRandomNumber(255)},${util.getRandomNumber(255)},${util.getRandomNumber(255)})`;
}
onMounted(() => {
  let dom = document.getElementsByClassName('canvas')[0];
  let width = dom.clientWidth;
  let height = dom.clientHeight;
  let camera = new Three.PerspectiveCamera(75, width / height, 0.1, 1000);
  camera.position.set(0, 0, 10);
  scene.add(camera);
  scene.add(axes);
  renderer.setSize(width, height);
  dom.appendChild(renderer.domElement);
  let controller = new OrbitControls(camera, renderer.domElement);
  controller.enableDamping = true;
  function render() {
    controller.update();
    renderer.render(scene, camera);
    state.taskFlag && requestAnimationFrame(render);
  }
  render();
});
onUnmounted(() => {
  state.taskFlag = false;
});
onActivated(() => {
  let ctl = {
    add() {
      for (let i = 0; i < state.addNum; i++) {
        const geometry = new Three.BufferGeometry();
        let x1 = util.getRandomNumber(3, -3, 1);
        let y1 = util.getRandomNumber(3, -3, 1);
        let z1 = util.getRandomNumber(3, -3, 1);
        let x2 = util.getRandomNumber(x1 + 2, x1 - 2, 1);
        let y2 = util.getRandomNumber(y1 + 2, y1 - 2, 1);
        let z2 = util.getRandomNumber(z1 + 2, z1 - 2, 1);
        let x3 = util.getRandomNumber(x1 + 2, x1 - 2, 1);
        let y3 = util.getRandomNumber(y1 + 2, y1 - 2, 1);
        let z3 = util.getRandomNumber(z1 + 2, z1 - 2, 1);
        let array = [x1, y1, z1, x2, y2, z2, x3, y3, z3];
        const vertices = new Float32Array(array);
        geometry.setAttribute('position', new Three.BufferAttribute(vertices, 3));
        const material = new Three.MeshBasicMaterial({
          color: getRandomColor(),
          transparent: true,
          opacity: util.getRandomNumber(0.7, 0.3, 1)
        });
        const mesh = new Three.Mesh(geometry, material);
        scene.add(mesh);
      }
    },
    remove() {
      let mesh = scene.children.find(i => i instanceof Three.Mesh);
      while (mesh) {
        scene.remove(mesh);
        mesh = scene.children.find(i => i instanceof Three.Mesh);
      }
    }
  };
  let gui = new GUI();
  gui.add(state, 'axesFlag').name('坐标轴').onChange(val => axes.visible = val);
  gui.add(state, 'addNum').name('添加个数').max(10).min(1);
  gui.add(ctl, 'add').name('添加图形');
  gui.add(ctl, 'remove').name('删除图形');
  state.gui = gui;
});
onDeactivated(() => {
  state.gui.destroy();
});
</script>
<style lang="scss">
.page-randomCubes {
  .canvas {
    width: 100%;
    height: 100%;
  }
}
</style>